'''
Author: didiplus
Description: 
Date: 2025-08-26 09:45:12
LastEditors: didiplus
LastEditTime: 2025-08-26 11:47:04
FilePath: /script/monitor/main.py
Version: 1.0
'''
import psutil
import socket
import requests
import datetime
import logging
from DingTalk import DingTalkPushUtil

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler('system_monitor.log'),
        logging.StreamHandler()
    ]
)
logger = logging.getLogger(__name__)

# 阈值配置（百分比）
THRESHOLD = {
    "cpu": 80,
    "mem": 75,
    "disk": 85
}

def get_host_info():
    """获取主机名和IP"""
    try:
        hostname = socket.gethostname()
        ip = socket.gethostbyname(hostname)
        logger.info(f"获取主机信息成功: {hostname} ({ip})")
        return hostname, ip
    except Exception as e:
        logger.error(f"获取主机信息失败: {e}")
        raise

def get_system_info():
    """获取CPU/内存/磁盘信息"""
    try:
        cpu_percent = psutil.cpu_percent(interval=1)
        mem = psutil.virtual_memory()
        disk = psutil.disk_usage('/')
        
        system_info = {
            "cpu": cpu_percent,
            "mem": mem.percent,
            "mem_total": round(mem.total / (1024**3), 2),
            "mem_used": round(mem.used / (1024**3), 2),
            "disk": disk.percent,
            "disk_total": round(disk.total / (1024**3), 2),
            "disk_used": round(disk.used / (1024**3), 2)
        }
        
        logger.info(f"系统资源状态 - CPU: {system_info['cpu']}%, "
                   f"内存: {system_info['mem']}%, "
                   f"磁盘: {system_info['disk']}%")
        return system_info
    except Exception as e:
        logger.error(f"获取系统信息失败: {e}")
        raise



def monitor():
    """监控并告警"""
    try:
        logger.info("开始系统监控检查")
        hostname, ip = get_host_info()
        info = get_system_info()

        alarm_item = []
        if info["cpu"] > THRESHOLD["cpu"]:
            alarm_item.append(f"- CPU 使用率：{info['cpu']}% > {THRESHOLD['cpu']}%")
        if info["mem"] > THRESHOLD["mem"]:
            alarm_item.append(f"- 内存使用率：{info['mem']}% > {THRESHOLD['mem']}%")
        if info["disk"] > THRESHOLD["disk"]:
            alarm_item.append(f"- 磁盘使用率：{info['disk']}% > {THRESHOLD['disk']}%")

        if alarm_item:  # 有异常才发告警
            content = f"""## 🚨 系统资源告警

---

### 🖥️ 主机信息
- **主机名**: {hostname}
- **IP地址**: {ip}
- **告警时间**: {datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")}

---

### ⚠️ 异常详情
{chr(10).join(alarm_item)}

---

### 📊 系统状态详情

#### 💻 CPU状态
- **使用率**: {info['cpu']}%
- **状态**: {"🔴 异常" if info["cpu"] > THRESHOLD["cpu"] else "🟢 正常"}

#### 🧠 内存状态
- **使用率**: {info['mem']}%
- **使用量**: {info['mem_used']} GB
- **总量**: {info['mem_total']} GB
- **状态**: {"🔴 异常" if info["mem"] > THRESHOLD["mem"] else "🟢 正常"}

#### 💾 磁盘状态
- **使用率**: {info['disk']}%
- **使用量**: {info['disk_used']} GB
- **总量**: {info['disk_total']} GB
- **状态**: {"🔴 异常" if info["disk"] > THRESHOLD["disk"] else "🟢 正常"}

---
> 📌 *请尽快处理系统资源异常，避免影响业务正常运行*
"""
            logger.warning(f"检测到系统异常，准备发送告警: {alarm_item}")
            DingTalkPushUtil().send_md("系统资源告警", content)
        else:
            logger.info("系统资源正常，无异常项")
    except Exception as e:
        logger.error(f"监控过程中发生错误: {e}")
        raise

if __name__ == "__main__":
    try:
        monitor()
        logger.info("监控任务执行完成")
    except Exception as e:
        logger.error(f"监控任务执行失败: {e}")